package ie.lawlor.amvc.event;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;

/**
 * 
 * @author blawlor
 */
public class ReflectionEventHandler implements IEventHandler {

	IEventSink target;
	protected Logger logger; 
	
	public ReflectionEventHandler(){
	}
	
	public ReflectionEventHandler(IEventSink target, String loggerName){
		this.target = target;
		setLoggerName(loggerName);
	}
	
	public void setLoggerName(String loggerName){
		logger = Logger.getLogger(loggerName);
	}
	
	public void setEventSink(IEventSink eventSink){
		this.target = eventSink;
	}
	
  public void handleEvent(Event e) throws EventNotHandledException {
    logger.debug("Entering: Handling " + e);
    Class c = target.getClass();
    try {
      String methodName = "do" + e.getName();
      Class[] argTypes = new Class[] { Event.class };
      Method doMethod = c.getMethod(
              methodName, argTypes);
      Object[] args = new Object[] { e };
      Object result = doMethod.invoke(
              target, args);
    } catch (SecurityException e1) {
      e1.printStackTrace();
      logger.error(
              "Couldn't call event handler (SecurityException)", e1);
    } catch (IllegalArgumentException e1) {
      e1.printStackTrace();
      logger.error(
              "Couldn't call event handler (IllegalArgumentException)", e1);
    } catch (NoSuchMethodException e1) {
      throw new EventNotHandledException("Event " + e
              + " not handled by reflection event handler", e1);
    } catch (IllegalAccessException e1) {
      e1.printStackTrace();
      logger.error(
              "Couldn't call event handler (IllegalAccessException)", e1);
    } catch (InvocationTargetException e1) {
      e1.printStackTrace();
      logger.error(
              "Couldn't call event handler (InvocationTargetException)", e1);
    }
  }

}
